package com.xjscrm.server.service.soptask.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.uzai.mobile.collect.api.dto.MicaTransDto;
import com.uzai.mobile.collect.api.dto.msg.MicaGroupMemberAddMsg;
import com.uzai.mobile.collect.api.dto.msg.consertoserver.MicaGroupAddTagMsg;
import com.uzai.trace.TraceGenerate;
import com.xjscrm.common.entity.*;
import com.xjscrm.common.enums.RedisCacheKeyEnum;
import com.xjscrm.common.utils.DateUtil;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.vo.grouppull.GroupPullData;
import com.xjscrm.common.vo.grouppull.GroupPullMsgData;
import com.xjscrm.common.vo.sop.GroupTigger;
import com.xjscrm.common.vo.sop.PlanData;
import com.xjscrm.server.common.util.DeviceTools;
import com.xjscrm.server.common.util.PlanDataTools;
import com.xjscrm.server.mapper.*;
import com.xjscrm.server.service.grouppull.GroupPullDataService;
import com.xjscrm.server.service.soptask.SopJobGroupService;
import com.xjscrm.server.service.soptask.SopJobMsgService;
import com.xjscrm.server.vo.device.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 增加群SOP任务
 *
 * @author makejava
 * @since 2024-03-01 17:01:12
 */
@Slf4j
@Service
public class SopJobGroupServiceImpl implements SopJobGroupService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SopTaskDeviceMapper sopTaskDeviceMapper;
    @Autowired
    private SopTaskMapper sopTaskMapper;
    @Autowired
    private SopJobMapper sopJobMapper;
    @Autowired
    private WwGroupTagsRelationMapper wwGroupTagsRelationMapper;
    @Autowired
    private WwGroupMapper wwGroupMapper;
    @Autowired
    private WwDeviceMapper wwDeviceMapper;
    @Autowired
    private WwCustomerMapper wwCustomerMapper;
    @Autowired
    private WwCustomerBlacklistMapper wwCustomerBlacklistMapper;
    @Autowired
    private GroupPullDataService groupPullDataService;
    @Autowired
    private SopJobMsgService sopJobMsgService;
    @Autowired
    private SopTemplateMapper sopTemplateMapper;

    /**
     * 添加SOP任务-手动群标签
     *
     * @param micaTransDto 手动群标签
     * @return 实例对象
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void addSopJobByGroupTag(MicaTransDto micaTransDto) {

        try {
            log.info("--监控系统日志--开始方法--");

            if (micaTransDto == null) {
                return;
            }

            if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                return;
            }

            MicaGroupAddTagMsg micaGroupAddTagMsg = JSONObject.parseObject(JSONObject.toJSONString(micaTransDto.getData()), MicaGroupAddTagMsg.class);
            if (micaGroupAddTagMsg == null) {
                return;
            }

            //限流key
            String limitKey = "-addSopJobByGroupTag-groupWxid-" + micaGroupAddTagMsg.getGroupWxid() + "_" + micaTransDto.getMerId();
            try {

                Object object = redisTemplate.opsForValue().get(limitKey);
                if (object != null) {
                    return;
                }
                //保存限流key
                redisTemplate.opsForValue().set(limitKey, limitKey, 100, TimeUnit.SECONDS);

                //查询此群是否已经有进行中的SOP任务
                SopJob sopJob_old = sopJobMapper.selectUniqueByGroupWxid(micaGroupAddTagMsg.getGroupWxid(), micaTransDto.getMerId());
                if (sopJob_old != null) { //此群有进行中的任务，则不添加
                    return;
                }

                //查询该机器人的配置方案
                log.info("--监控系统日志--查询机器人--");
                WwDevice wwDevice = wwDeviceMapper.queryByDeviceId(micaTransDto.getDeviceId(), micaTransDto.getMerId());
                if (wwDevice == null) {
                    return;
                }
                Device device = DeviceTools.transDevice(wwDevice);
                if (device == null) {
                    return;
                }

                //查询该机器人配置的打标签SOP任务列表
                log.info("--监控系统日志--查询该机器人配置的打标签SOP任务列表--");
                List<SopTaskDevice> sopTaskDeviceList = sopTaskDeviceMapper.selectByDeivceUniqueIdAndType(device.getDeviceUniqueId(), 4, device.getMerId());
                if (sopTaskDeviceList != null && sopTaskDeviceList.size() >= 0) {

                    //查询到任务
                    SopTask sopTask = verifyGroupTag(sopTaskDeviceList, device, micaGroupAddTagMsg);
                    if (sopTask != null) {
                        //查询符合条件的任意一个新客SOP方案(新会员SOP只触发一个)
                        if (sopTask.getTeaplateId() == null) {
                            return;
                        }
                        log.info("--监控系统日志--查询sop模板--");
                        SopTemplate sopTemplate = sopTemplateMapper.selectById(sopTask.getTeaplateId());
                        if (sopTemplate == null) {
                            return;
                        }

                        String planDatas = sopTemplate.getPlanDatas();
                        if (StringUtils.isBlank(planDatas)) {
                            return;
                        }

                        List<PlanData> planDataList = JSONObject.parseArray(planDatas, PlanData.class);
                        if (planDataList == null || planDataList.size() == 0) {
                            return;
                        }
                        //当前时间
                        int now = DateUtil.getTime();
                        //计算发送时间
                        Integer sendTime = PlanDataTools.getSendTime(null, planDataList.get(0));
                        //保存SopJob
                        SopJob sopJob = new SopJob();
                        sopJob.setId(IdWorker.getId());
                        sopJob.setMerId(sopTask.getMerId());
                        sopJob.setTaskId(sopTask.getId());
                        sopJob.setName(sopTask.getName());
                        sopJob.setStatus(1);
                        sopJob.setType(sopTask.getType());
                        sopJob.setTeaplateId(sopTask.getTeaplateId());
                        sopJob.setTrigger(sopTask.getTrigger());
                        sopJob.setPlanDatas(sopTemplate.getPlanDatas());
                        sopJob.setWxid(micaGroupAddTagMsg.getGroupWxid());
                        sopJob.setDeviceUniqueId(device.getDeviceUniqueId());
                        sopJob.setDeviceId(device.getDeviceId());
                        sopJob.setFirstTime(sendTime);
                        sopJob.setNextTime(sendTime);
                        sopJob.setPlanDatasNextIndex(0);
                        sopJob.setWxidType(1);//类型（0-客户;1-群）
                        sopJob.setCreateTime(now);
                        sopJob.setUpdateTime(now);
                        sopJobMapper.insertSelective(sopJob);

                        log.info("--监控系统日志--查询sop数据--");
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                //删除限流key
                redisTemplate.delete(limitKey);
            }

        }catch (Exception e){
            log.error(e.getMessage(), e);
        }finally {
            log.info("--监控系统日志--结束方法--");
        }

    }

    /**
     * 查找符合新客户运营的SOP任务，只查询符合条件的一个任务
     *
     * @param sopTaskDeviceList
     * @return null
     * @author jitwxs
     * @date 2024/4/22 12:00
     */
    private SopTask verifyGroupTag(List<SopTaskDevice> sopTaskDeviceList, Device device, MicaGroupAddTagMsg micaGroupAddTagMsg) {
        List<WwGroupTagsRelation> wwGroupTagsRelationList = wwGroupTagsRelationMapper.selectByDeviceIdAndGroupWxid(device.getMerId(), device.getDeviceId(), micaGroupAddTagMsg.getGroupWxid());
        if (wwGroupTagsRelationList == null) {
            return null;
        }

        List<Long> wwGroupTagedList = new ArrayList<>();
        if (wwGroupTagsRelationList != null && wwGroupTagsRelationList.size() > 0) {
            for (WwGroupTagsRelation wwGroupTagsRelation : wwGroupTagsRelationList) {
                wwGroupTagedList.add(wwGroupTagsRelation.getTagId());
            }
        }

        //在群人数
        String groupMemberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), micaGroupAddTagMsg.getGroupWxid());
        Integer groupMemberCount = (Integer) redisTemplate.opsForValue().get(groupMemberCountKey);
        Integer memberTotal = Tools.getInteger(groupMemberCount);

        //新客SOP任务
        SopTask sopTask = null;
        //条件验证
        for (SopTaskDevice sopTaskDevice : sopTaskDeviceList) {
            try {
                sopTask = sopTaskMapper.selectById(sopTaskDevice.getTaskId());
                if (sopTask != null && sopTask.getStatus().intValue() == 1) {
                    GroupTigger groupTigger = JSONObject.parseObject(sopTask.getTrigger(), GroupTigger.class);
                    if (groupTigger != null) {
                        //群标签开关(0-关闭;1-开启)
                        boolean tagFlag = false; //默认关闭
                        Integer groupTagSwitch = Tools.getInteger(groupTigger.getGroupTagSwitch());
                        if (groupTagSwitch.intValue() == 1) { //开启群标签开关
                            List<Long> groupTagIdList = JSONObject.parseArray(groupTigger.getGroupTags(), Long.class);
                            for (Long groupTagId : groupTagIdList) {
                                if (wwGroupTagedList.contains(groupTagId)) {//找到一个符合的，就返回通过
                                    tagFlag = true;
                                    break;
                                }
                            }
                        }

                        if (tagFlag) {//标签符合，再去验证群人数
                            //群人数验证开关
                            boolean groupMemberCountFlag = false; //默认关闭
                            Integer groupMemberCountSwitch = Tools.getInteger(groupTigger.getGroupMemberCountSwitch());
                            if (groupMemberCountSwitch.intValue() == 1) {
                                Integer groupMemberCount_config = Tools.getInteger(groupTigger.getGroupMemberCount());
                                //验证群人数
                                if (memberTotal.intValue() >= groupMemberCount_config.intValue()) {
                                    return sopTask;
                                }
                            } else {
                                return sopTask;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }

        return null;
    }

    /**
     * 添加SOP任务-手动群标签
     *
     * @param micaTransDto 手动群标签
     * @return 实例对象
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void addSopJobByGroupMenberCount(MicaTransDto micaTransDto) {

        try {
            log.info("监控日志-开始");

            if (micaTransDto == null) {
                return;
            }

            if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                return;
            }

            MicaGroupMemberAddMsg micaGroupMemberAddMsg = JSONObject.parseObject(micaTransDto.getData().toString(), MicaGroupMemberAddMsg.class);
            if (micaGroupMemberAddMsg == null) {
                return;
            }

            //限流key
            String limitKey = "-addSopJobByGroupMenberCount-groupWxid-" + micaGroupMemberAddMsg.getGroupId() + "_" + micaTransDto.getMerId();
            try {
                Object object = redisTemplate.opsForValue().get(limitKey);
                if (object != null) {
                    return;
                }
                //保存限流key
                redisTemplate.opsForValue().set(limitKey, limitKey, 100, TimeUnit.SECONDS);

                //查询此群是否已经有进行中的SOP任务
                SopJob sopJob_old = sopJobMapper.selectUniqueByGroupWxid(micaGroupMemberAddMsg.getGroupId(), micaTransDto.getMerId());
                if (sopJob_old != null) { //此群有进行中的任务，则不添加
                    return;
                }

                if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                    return;
                }

                //查询该机器人的配置方案
                WwDevice wwDevice = wwDeviceMapper.queryByDeviceId(micaTransDto.getDeviceId(), micaTransDto.getMerId());
                if (wwDevice == null) {
                    return;
                }
                Device device = DeviceTools.transDevice(wwDevice);
                if (device == null) {
                    return;
                }

                //查询该机器人配置的打标签SOP任务列表
                List<SopTaskDevice> sopTaskDeviceList = sopTaskDeviceMapper.selectByDeivceUniqueIdAndType(device.getDeviceUniqueId(), 4, device.getMerId());
                if (sopTaskDeviceList != null && sopTaskDeviceList.size() >= 0) {

                    //查询到任务
                    SopTask sopTask = verifyGroupMemberCount(sopTaskDeviceList, device, micaGroupMemberAddMsg);
                    if (sopTask != null) {
                        //查询符合条件的任意一个新客SOP方案(新会员SOP只触发一个)
                        if (sopTask.getTeaplateId() == null) {
                            return;
                        }

                        SopTemplate sopTemplate = sopTemplateMapper.selectById(sopTask.getTeaplateId());
                        if (sopTemplate == null) {
                            return;
                        }
                        String planDatas = sopTemplate.getPlanDatas();
                        if (StringUtils.isBlank(planDatas)) {
                            return;
                        }

                        List<PlanData> planDataList = JSONObject.parseArray(planDatas, PlanData.class);
                        if (planDataList == null || planDataList.size() == 0) {
                            return;
                        }
                        //当前时间
                        int now = DateUtil.getTime();
                        //计算发送时间
                        Integer sendTime = PlanDataTools.getSendTime(null, planDataList.get(0));
                        //保存SopJob
                        SopJob sopJob = new SopJob();
                        sopJob.setId(IdWorker.getId());
                        sopJob.setMerId(sopTask.getMerId());
                        sopJob.setTaskId(sopTask.getId());
                        sopJob.setName(sopTask.getName());
                        sopJob.setStatus(1);
                        sopJob.setType(sopTask.getType());
                        sopJob.setTeaplateId(sopTask.getTeaplateId());
                        sopJob.setTrigger(sopTask.getTrigger());
                        sopJob.setPlanDatas(sopTemplate.getPlanDatas());
                        sopJob.setWxid(micaGroupMemberAddMsg.getGroupId());
                        sopJob.setDeviceUniqueId(device.getDeviceUniqueId());
                        sopJob.setDeviceId(device.getDeviceId());
                        sopJob.setFirstTime(sendTime);
                        sopJob.setNextTime(sendTime);
                        sopJob.setPlanDatasNextIndex(0);
                        sopJob.setWxidType(1);//类型（0-客户;1-群）
                        sopJob.setCreateTime(now);
                        sopJob.setUpdateTime(now);
                        sopJobMapper.insertSelective(sopJob);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                //删除限流key
                redisTemplate.delete(limitKey);
            }

        }catch (Exception e){
            log.error(e.getMessage(), e);
        }finally {
            log.info("监控日志-结束");
        }
    }

    /**
     * 查找符合新客户运营的SOP任务，只查询符合条件的一个任务
     *
     * @param sopTaskDeviceList
     * @return null
     * @author jitwxs
     * @date 2024/4/22 12:00
     */
    private SopTask verifyGroupMemberCount(List<SopTaskDevice> sopTaskDeviceList, Device device, MicaGroupMemberAddMsg micaGroupMemberAddMsg) {
        List<WwGroupTagsRelation> wwGroupTagsRelationList = wwGroupTagsRelationMapper.selectByDeviceIdAndGroupWxid(device.getMerId(), device.getDeviceId(), micaGroupMemberAddMsg.getGroupId());
        if (wwGroupTagsRelationList == null) {
            return null;
        }

        List<Long> wwGroupTagedList = new ArrayList<>();
        if (wwGroupTagsRelationList != null && wwGroupTagsRelationList.size() > 0) {
            for (WwGroupTagsRelation wwGroupTagsRelation : wwGroupTagsRelationList) {
                wwGroupTagedList.add(wwGroupTagsRelation.getTagId());
            }
        }

        //在群人数
        String groupMemberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), micaGroupMemberAddMsg.getGroupId());
        Integer groupMemberCount = (Integer) redisTemplate.opsForValue().get(groupMemberCountKey);
        Integer memberTotal = Tools.getInteger(groupMemberCount);

        //新客SOP任务
        SopTask sopTask = null;
        //条件验证
        for (SopTaskDevice sopTaskDevice : sopTaskDeviceList) {
            try {
                sopTask = sopTaskMapper.selectById(sopTaskDevice.getTaskId());
                if (sopTask != null && sopTask.getStatus().intValue() == 1) {
                    GroupTigger groupTigger = JSONObject.parseObject(sopTask.getTrigger(), GroupTigger.class);
                    if (groupTigger != null) {

                        //群人数验证开关
                        boolean groupMemberCountFlag = false; //默认关闭
                        Integer groupMemberCountSwitch = Tools.getInteger(groupTigger.getGroupMemberCountSwitch());
                        if (groupMemberCountSwitch.intValue() == 1) {
                            Integer groupMemberCount_config = Tools.getInteger(groupTigger.getGroupMemberCount());
                            //验证群人数
                            if (memberTotal.intValue() >= groupMemberCount_config.intValue()) {
                                groupMemberCountFlag = true;
                            }
                        }

                        //群人数符合，在去判断是否开启群标签验证
                        if (groupMemberCountFlag) {
                            Integer groupTagSwitch = Tools.getInteger(groupTigger.getGroupTagSwitch());
                            if (groupTagSwitch.intValue() == 1) { //开启群标签开关
                                List<Long> groupTagIdList = JSONObject.parseArray(groupTigger.getGroupTags(), Long.class);
                                for (Long groupTagId : groupTagIdList) {
                                    if (wwGroupTagedList.contains(groupTagId)) {//找到一个符合的，就返回通过
                                        return sopTask;
                                    }
                                }
                            } else {
                                return sopTask;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }

        return null;
    }

    /**
     * 自动处理群SOP阶段性任务
     *
     * @param sopJob
     * @return null
     * @author jitwxs
     * @date 2024/3/8 17:12
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void autoStepSopJobByGroup(SopJob sopJob) {

        try {

            log.info("监控日志-开始");

            if (sopJob == null) {
                return;
            }

            //获取该任务计划数据
            String planDatas = sopJob.getPlanDatas();
            if (StringUtils.isBlank(planDatas)) {
                return;
            }

            List<PlanData> planDataList = JSONObject.parseArray(planDatas, PlanData.class);
            if (planDataList == null || planDataList.size() == 0) {
                return;
            }

            int now = DateUtil.getTime();

            //获取当前阶段性数据的下标
            Integer planDatasNextIndex = Tools.getInteger(sopJob.getPlanDatasNextIndex());
            //如果下标已经超过数据的长度，则将任务修改成已完成
            if (planDatasNextIndex >= planDataList.size()) {
                sopJob.setStatus(2); //执行完成
                sopJob.setUpdateTime(now);
                sopJobMapper.updateStatusById(sopJob);
                return;
            }

            //查询机器人
            WwDevice wwDevice = wwDeviceMapper.queryById(sopJob.getDeviceUniqueId());
            if (wwDevice == null) {
                sopJob.setStatus(0); //执行关闭
                sopJob.setUpdateTime(now);
                sopJob.setRemark("机器人未找到");
                sopJobMapper.updateStatusById(sopJob);
                return;
            }
            Device device = DeviceTools.transDevice(wwDevice);

            //查询会员
            String sendNickname = null;
            WwGroup wwGroup = wwGroupMapper.queryByDeviceUniqueIdAndGroupWxid(sopJob.getDeviceUniqueId(), sopJob.getWxid());
            if (wwGroup == null) { //群不存在
                sopJob.setStatus(0); //执行关闭
                sopJob.setUpdateTime(now);
                sopJob.setRemark("群未找到");
                sopJobMapper.updateStatusById(sopJob);
                return;
            }

            //群现在的标签
            List<WwGroupTagsRelation> wwGroupTagsRelationList = wwGroupTagsRelationMapper.selectByDeviceIdAndGroupWxid(device.getMerId(), device.getDeviceId(), sopJob.getWxid());
            List<Long> wwGroupTagedList = new ArrayList<>();
            if (wwGroupTagsRelationList != null && wwGroupTagsRelationList.size() > 0) {
                for (WwGroupTagsRelation wwGroupTagsRelation : wwGroupTagsRelationList) {
                    wwGroupTagedList.add(wwGroupTagsRelation.getTagId());
                }
            }
            //拉群触发条件
            GroupTigger groupTigger = JSONObject.parseObject(sopJob.getTrigger(), GroupTigger.class);
            //验证群标签是否符合条件
            boolean result = verifyGroupTagByStep(groupTigger, wwGroupTagedList);
            if (!result) {
                sopJob.setStatus(0); //执行关闭
                sopJob.setUpdateTime(now);
                sopJob.setRemark("群标签不符合条件");
                sopJobMapper.updateStatusById(sopJob);
                return;
            }

            //本次的执行时间
            Integer sendTime_this = Tools.getInteger(sopJob.getNextTime());
            //获取当前需要发送的阶段性计划数据
            if(planDatasNextIndex < planDataList.size()){
                PlanData planData = planDataList.get(planDatasNextIndex);
                if (planData != null) {
                    List<GroupPullData> groupPullDataList = planData.getMsgDataList();
                    if (groupPullDataList != null) {
                        List<GroupPullMsgData> groupPullMsgDataList = groupPullDataService.handGroupPullData(sopJob.getMerId(), groupPullDataList, null, device);
                        if (groupPullMsgDataList != null && groupPullMsgDataList.size() > 0) {
                            sopJobMsgService.addSopJobMsg(sopJob, sendTime_this, device, sopJob.getWxid(), sendNickname, groupPullMsgDataList);
                        }
                    }
                }
            }

            //计算下次发送时间
            if(planDatasNextIndex + 1 >= planDataList.size()){//没有下次，则直接修改成完成
                sopJob.setStatus(2);
                sopJob.setUpdateTime(now);
                sopJobMapper.updateStatusById(sopJob);
            }else{
                Integer sendTime_next = PlanDataTools.getSendTime(sopJob.getFirstTime(), planDataList.get(planDatasNextIndex + 1));
                sopJob.setNextTime(sendTime_next);
                sopJob.setPlanDatasNextIndex(planDatasNextIndex + 1);
                sopJob.setUpdateTime(now);
                sopJobMapper.updateStatusById(sopJob);
            }
        }catch (Exception e){
            log.error(e.getMessage(), e);
        }finally {
            log.info("监控日志-结束");
        }
    }

    /**
     * 验证符合阶段性群SOP任务条件
     *
     * @param groupTigger
     * @return 符合返回true
     * @author jitwxs
     * @date 2024/4/22 12:00
     */
    private boolean verifyGroupTagByStep(GroupTigger groupTigger, List<Long> wwGroupTagedList) {
        try {
            if (groupTigger != null) {
                Integer groupTagSwitch = Tools.getInteger(groupTigger.getGroupTagSwitch());
                if (groupTagSwitch.intValue() == 1) { //开启群标签开关
                    List<Long> groupTagIdList = JSONObject.parseArray(groupTigger.getGroupTags(), Long.class);
                    for (Long groupTagId : groupTagIdList) {
                        if (wwGroupTagedList.contains(groupTagId)) {//找到一个符合的，就返回通过
                            return true;
                        }
                    }
                } else {
                    return true;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return false;
    }

}
